﻿using System;
using System.Collections.Generic;
using System.Linq;
using EPiBoost.Core.Interfaces.Base;
using EPiServer.DataAbstraction;
using EPiServer.Framework;
using EPiServer.Framework.DataAnnotations;
using EPiServer.Framework.Initialization;
using EPiServer.ServiceLocation;
using EPiServer.Web.Mvc;

namespace EPiBoost.Core.Initialization
{

	[ServiceConfiguration(typeof (IViewTemplateModelRegistrator))]
	[ModuleDependency(typeof (ServiceContainerInitialization))]
	[InitializableModule]
	public class BasePagePartialControllerInitializer : IInitializableModule, IViewTemplateModelRegistrator
	{

		public void Initialize(InitializationEngine context)
		{ 
			if(!Configuration.Core.Initialization.BasePagePartialControllerInitializerEnabled)
			{
				return;
			}

			var repo = context.Locate.Advanced.GetInstance<TemplateModelRepository>();

			var types = FindAllInterfaceTypes<IBasePagePartialController>().Where(t=> !t.IsGenericType && t.IsClass);
			foreach(var t in types)
			{
				if (t.BaseType != null)
				{
					var pageType = t.BaseType.GetGenericArguments().First();
					var templateModel = new TemplateModel()
					                    	{
					                    		Name = t.Name,
					                    		TemplateType = t,
					                    		TemplateTypeCategory = EPiServer.Framework.Web.TemplateTypeCategories.MvcPartialController
					                    	};

					var renderDescriptor = t.GetCustomAttributes(typeof(TemplateDescriptorAttribute), false).OfType<TemplateDescriptorAttribute>().FirstOrDefault();
				
					if(renderDescriptor!=null)
					{
						templateModel.Tags = renderDescriptor.Tags;
						templateModel.AvailableWithoutTag = renderDescriptor.AvailableWithoutTag;
						templateModel.Default = renderDescriptor.Default;
					}
				
					repo.RegisterTemplate(pageType, templateModel);
				}
			}
		}

		private static IEnumerable<Type> FindAllInterfaceTypes<T>()
		{
			var type = typeof(T);
			var types = AppDomain.CurrentDomain.GetAssemblies().ToList()
				.SelectMany(s => s.GetTypes())
				.Where(type.IsAssignableFrom);

			return types;
		}


		public void Preload(string[] parameters){}
		public void Uninitialize(InitializationEngine context){}
		public void Register(TemplateModelCollection viewTemplateModelRegistrator){}

	 
	}
}

